package com.chenfan.ccp.plug.mq.listener;

import javassist.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.env.ConfigurableEnvironment;

import java.util.Objects;

/**
 * @author xutong
 */

@Slf4j
public class InitialListener implements ApplicationListener<ApplicationPreparedEvent> {
    public static volatile int flag = 0;

    @Override
    public void onApplicationEvent(ApplicationPreparedEvent applicationPreparedEvent) {
        //修改org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer
        try {
            if (flag != 0) {
                return;
            }
            ConfigurableEnvironment environment = applicationPreparedEvent.getApplicationContext().getEnvironment();
            // 没有配置rocketmq
            String property = environment.getProperty("rocketmq.name-server");
            if (StringUtils.isBlank(property)) {
                return;
            }
            flag = 1;
            log.info("InitialListener 开始加载");
            ClassPool pool = ClassPool.getDefault();
            ClassClassPath classPath = new ClassClassPath(this.getClass());
            pool.insertClassPath(classPath);
            pool.appendClassPath("org/apache/rocketmq/spring/support/");
            CtClass cc = pool.getOrNull("org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer");
            if (Objects.isNull(cc)) {
                return;
            }
            CtMethod message = cc.getDeclaredMethod("doConvertMessage");
            message.insertBefore(
                    "String property = messageExt.getProperty(com.chenfan.ccp.constants.Constants.TRACE_ID_HEAD); " +
                    "com.chenfan.ccp.plug.log.util.TraceIdUtil.traceRpc(property); "+
                    "            String user = messageExt.getProperty(com.chenfan.ccp.constants.Constants.CURRENT_USER);\n" +
                            "            com.chenfan.ccp.entity.BaseUserVO baseUserVO = com.alibaba.fastjson.JSON.parseObject(user, com.chenfan.ccp.entity.BaseUserVO.class);\n" +
                            "            com.chenfan.ccp.plug.business.constants.Constants.USER_ID.set(baseUserVO);"
                    );
            CtMethod handleMessage = cc.getDeclaredMethod("handleMessage");
            handleMessage.insertAfter("com.chenfan.ccp.plug.business.constants.Constants.USER_ID.remove();");
            Object person = cc.toClass().newInstance();
            CtClass template = pool.get("org.apache.rocketmq.spring.core.RocketMQTemplate");
            CtMethod createRocketMqMessage = template.getDeclaredMethod("doConvert");
            createRocketMqMessage.insertBefore("headers = new java.util.HashMap(headers); " +
                    "headers.putIfAbsent(com.chenfan.ccp.constants.Constants.TRACE_ID_HEAD, com.chenfan.ccp.plug.log.util.TraceIdUtil.getTraceId()); "+
                    "headers.putIfAbsent(com.chenfan.ccp.constants.Constants.CURRENT_USER, com.alibaba.fastjson.JSON.toJSONString(com.chenfan.ccp.plug.business.constants.Constants.USER_ID.get()));"
                    );
            template.toClass().newInstance();
            log.info("InitialListener 完成加载");
        } catch (NotFoundException | CannotCompileException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}
